﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using opensj;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ReadDogv1
{
    /// <summary>
    /// UcCreatedog.xaml 的交互逻辑
    /// </summary>
    public partial class UcCreatedog : UserControl
    {
        public UcCreatedog()
        {
            InitializeComponent();
            DataContext = ViewModel.GetInstance().doglistData;
        }

        private async void Button_ClickAsync(object sender, RoutedEventArgs e)
        {
            ViewModel.GetInstance().doglistData.ThreadRun();
            ((Button)sender).IsEnabled = false;
        }


        private void Button_ClickAsync_C1(object sender, RoutedEventArgs e)
        {
            if (ViewModel.GetInstance().doglistData.线程状态.Equals("闲置中"))
            {
                ViewModel.GetInstance().log.DebugLog($"按钮 【{((Button)sender).Content}】 成功");
                ViewModel.GetInstance().doglistData.开始检查任务();
            }
        }

        private void Button_ClickAsync_S2(object sender, RoutedEventArgs e)
        {
            if (!ViewModel.GetInstance().doglistData.线程状态.Equals("闲置中"))
            {
                ViewModel.GetInstance().log.DebugLog($"按钮 【{((Button)sender).Content}】 成功");
                ViewModel.GetInstance().doglistData.停止线程();
            }
        }

        private void Button_ClickAsync_S1(object sender, RoutedEventArgs e)
        {
            if (ViewModel.GetInstance().doglistData.线程状态.Equals("闲置中"))
            {
                ViewModel.GetInstance().log.DebugLog($"按钮 【{((Button)sender).Content}】 成功");
                ViewModel.GetInstance().doglistData.开始烧录任务();
            }
        }

        private void Button_ClickAsync_T2(object sender, RoutedEventArgs e)
        {
            ViewModel.GetInstance().doglistData.母狗状态 = "未存在";
            ViewModel.GetInstance().doglistData.子狗状态 = "未存在";
        }

        private void Button_ClickAsync_T1(object sender, RoutedEventArgs e)
        {
            ViewModel.GetInstance().doglistData.母狗状态 = "存在";
            ViewModel.GetInstance().doglistData.子狗状态 = "存在";
        }

        private void Button_ClickAsync_TT1(object sender, RoutedEventArgs e)
        {
            try
            {
                ((Button)sender).IsEnabled = false;
                int nCnt = int.Parse(_T3.Text);
                ViewModel.GetInstance().doglistData.create_dogTask(_T1.Text, nCnt);
                ViewModel.GetInstance().doglistData.RefreshDogList();
            }
            catch (Exception ex)
            {

                MessageBox.Show($"{ex.Message}");
            }
            ((Button)sender).IsEnabled = true;
        }

        private async void Button_ClickAsync_TT0(object sender, RoutedEventArgs e)
        {
            ((Button)sender).IsEnabled = false;
            await ViewModel.GetInstance().doglistData.get_enable_dogList();
            var obj = ViewModel.GetInstance().doglistData.GetDogList();
            C1.Items.Clear();
            foreach (var item in obj)
            {
                C1.Items.Add(item);
            }
            ((Button)sender).IsEnabled = true;
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;

            if (comboBox.SelectedItem != null)
            {
                int selectedItem = comboBox.SelectedIndex;
                var obj = ViewModel.GetInstance().doglistData.GetDogList();

                var 物料编码 = obj[selectedItem];
                var 物料规格 = "";
                ViewModel.GetInstance().doglistData.GetDoginfo(ref 物料编码, ref 物料规格);
                _T1.Text = 物料编码;
                _T2.Text = 物料规格;
            }
        }

        private void button_Delete_Click(object sender, RoutedEventArgs e)
        {
            if (doglist.SelectedIndex < 0)
                return;
            ViewModel.GetInstance().doglistData.DeleteListTask(doglist.SelectedIndex.ToString());
        }
    }


    public class model_doglist : ThreadEX, INotifyPropertyChanged
    {
        #region MVVM声明 

        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        public model_doglist()
        {
            this.m_ThreadName = "model_doglist";
            this.m_ThreadSleep = 200;

        }

        public void ThreadRun()
        {
            Start();
            Pasue();
        }

        public override async Task OnasyncRun()
        {
            母狗状态 = CsHansdog.F_CheckDogExist();
            子狗状态 = 母狗状态;

            switch (线程状态)
            {
                case "烧录中":
                    await 进行一次烧录判断();
                    break;
                case "检查中":
                    await 进行一次检查判断();
                    break;
                default:
                    break;
            }
        }

        public override void OnPasue()
        {
            母狗状态 = CsHansdog.F_CheckDogExist();
            子狗状态 = 母狗状态;
        }

        public void 开始烧录任务()
        {
            线程状态 = "烧录中";
            ViewModel.GetInstance().log.DebugLog($"==========================================================================");
            asyncRun();
        }

        public void 开始检查任务()
        {
            线程状态 = "检查中";
            ViewModel.GetInstance().log.DebugLog($"==========================================================================");
            asyncRun();
        }

        public void 停止线程()
        {
            线程状态 = "闲置中";
            任务序号 = "";
            任务状态 = "未开始";
            ViewModel.GetInstance().log.DebugLog($"==========================================================================");
            Pasue();
        }

        public async Task 进行一次烧录判断()
        {
            var 任务单ID = "";
            try
            {
                if (是否可烧录)
                {
                    //插入子加密狗
                    var result = m_dicDogList.Values.Where(x => x.烧录状态 == "未烧录");
                    if (result.Count() == 0)
                    {
                        任务序号 = "";
                        任务状态 = "未开始";
                        ViewModel.GetInstance().log.DebugLog($"---烧录任务完成，停止烧录任务");
                        停止线程();
                    }
                    foreach (CsDogitem item in result)
                    {
                        任务单ID = m_dicDogList.First(x => x.Value == item).Key;//任务单ID
                        任务序号 = m_DogList.FirstOrDefault(x => x.任务单ID == 任务单ID).序号;
                        任务状态 = "烧录中";
                        m_dicDogList[任务单ID].是否正在烧录 = "是";
                        RefreshDogList();
                        ViewModel.GetInstance().log.DebugLog($"---烧录任务【{任务序号}】开始");

                        #region  启动烧录
                        var DMS注册信息 = "";
                        if (CsHansdog.F_CreateDogInfo(item.物料编码, item.规格型号, 任务单ID, ref DMS注册信息))
                        {
                            var JsStr = await register_dog(DMS注册信息);
                            if (!JsStr.Contains("err"))
                            {
                                JObject obj = JObject.Parse(DMS注册信息);
                                var 加密狗ID = obj.GetValue("加密狗ID").ToString();
                                var 设备启动激活码 = obj.GetValue("设备启动激活码").ToString();
                                var 设备终止激活码 = obj.GetValue("设备终止激活码").ToString();
                                var 服务完成激活码 = obj.GetValue("服务完成激活码").ToString();
                                任务状态 = "烧录完成";
                                m_dicDogList[任务单ID].激活码 = $"{设备启动激活码},{设备终止激活码},{服务完成激活码}";
                                m_dicDogList[任务单ID].加密狗ID = 加密狗ID;
                                m_dicDogList[任务单ID].烧录状态 = "已烧录";
                                m_dicDogList[任务单ID].是否正在烧录 = "否";
                                ViewModel.GetInstance().log.DebugLog($"---烧录任务【{任务序号}】完成，请拔出子狗");
                            }
                            else
                            {
                                任务状态 = "烧录失败";
                                m_dicDogList[任务单ID].是否正在烧录 = "异常";
                                ViewModel.GetInstance().log.DebugLog($"---烧录任务【{任务序号}】失败，停止烧录任务，上传DMS服务器失败，请检查网路环境，单击【开始烧录任务】进行重新烧录");
                                停止线程();
                            }
                        }
                        else
                        {
                            任务状态 = "烧录失败";
                            m_dicDogList[任务单ID].是否正在烧录 = "异常";
                            ViewModel.GetInstance().log.DebugLog($"---烧录任务【{任务序号}】失败，停止烧录任务，烧录程序失败，请检查烧录环境，单击【开始烧录任务】进行重新烧录");
                            停止线程();
                        }
                        RefreshDogList();
                        是否可烧录 = false;
                        #endregion
                        break;//仅烧录第一条
                    }
                }
            }
            catch (Exception ex)
            {
                //正常不进入
                是否可烧录 = false;
                任务状态 = "烧录失败";
                m_dicDogList[任务单ID].烧录状态 = "未烧录";
                m_dicDogList[任务单ID].是否正在烧录 = "异常";
                RefreshDogList();
                ViewModel.GetInstance().log.DebugLog($"---烧录任务【{任务序号}】异常失败，停止烧录任务，{ex.Message}");
                停止线程();
            }
        }

        public async Task 进行一次检查判断()
        {
            try
            {
                if (是否可烧录)
                {
                    var 检查信息 = "";
                    var 加密狗ID = "";
                    var 激活码 = "";
                    var 设备启动激活码 = "";
                    var 设备终止激活码 = "";
                    var 服务完成激活码 = "";
                    if (CsHansdog.F_ReadDogInfo(ref 加密狗ID, ref 激活码))
                    {
                        var 激活码List = 激活码.Split(';');
                        if (激活码List.Count() == 3)
                        {
                            设备启动激活码 = 激活码List[0];
                            设备终止激活码 = 激活码List[1];
                            服务完成激活码 = 激活码List[2];
                        }

                        var js = new
                        {
                            加密狗ID = 加密狗ID,
                            设备启动激活码 = 设备启动激活码,
                            设备终止激活码 = 设备终止激活码,
                            服务完成激活码 = 服务完成激活码,
                        };
                        检查信息 = JsonConvert.SerializeObject(js);
                        ViewModel.GetInstance().log.DebugLog($"---加密狗信息【本地】，【{检查信息}】");
                        //联网检查
                        var JsStr = await check_dog(检查信息);
                        if (!JsStr.Contains("err"))
                        {
                            JObject obj = JObject.Parse(JsStr);
                            var 校验状态 = obj.GetValue("校验状态").ToString();
                            var 物料编码 = obj.GetValue("物料编码").ToString();
                            var 物料规格 = obj.GetValue("物料规格").ToString();
                            if (校验状态.Equals("成功"))
                            {
                                ViewModel.GetInstance().log.DebugLog($"---检查任务完成【联网】校验成功，物料编码：{物料编码}，物料规格：{物料规格}");
                            }
                            else
                            {
                                ViewModel.GetInstance().log.DebugLog($"---检查任务完成，当前加密狗【未注册】至DMS服务器");
                            }
                        }
                        else
                        {
                            ViewModel.GetInstance().log.DebugLog($"---检查任务失败【联网】，请检查DMS服务器");
                        }
                    }
                    else
                    {
                        ViewModel.GetInstance().log.DebugLog($"---检查任务失败，读加密狗信息失败");
                    }
                    是否可烧录 = false;
                }
            }
            catch (Exception ex)
            {
                //正常不进入
                是否可烧录 = false;
                ViewModel.GetInstance().log.DebugLog($"---检查任务失败，{ex.Message}");
                停止线程();
            }
        }

        //实际后台数据，实施同步SQL更新
        public Dictionary<string, CsDogitem> m_dicDogList = new Dictionary<string, CsDogitem>();

        public void DeleteListTask(string nIndex)
        {
            m_dicDogList[nIndex].烧录状态 = "失效";
            RefreshDogList();
        }

        //实际后台数据，实施同步SQL更新
        private Dictionary<string, CsDogitem> m_dicDogList_new = new Dictionary<string, CsDogitem>();
        public List<string> GetDogList()
        {
            List<string> obj = new List<string>();

            foreach (var item in m_dicDogList_new)
            {
                obj.Add(item.Value.物料编码);
            }
            return obj;
        }

        public void GetDoginfo(ref string 物料编码, ref string 物料规格)
        {
            if (m_dicDogList_new.TryGetValue(物料编码, out var val))
            {
                物料编码 = val.物料编码;
                物料规格 = val.规格型号;
            }
        }

        public void create_dogTask(string 物料编码, int nCnt)
        {
            for (int i = 0; i < nCnt; i++)
            {
                if (m_dicDogList_new.TryGetValue(物料编码, out var val))
                {
                    CsDogitem dogitem = new CsDogitem()
                    {
                        选择 = false,
                        序号 = m_dicDogList.Count.ToString(),
                        物料编码 = 物料编码,
                        物料名称 = "视觉狗",
                        规格型号 = val.规格型号,
                        激活码 = "",
                        加密狗ID = "",
                        任务单ID = m_dicDogList.Count.ToString(),
                        烧录状态 = "未烧录",
                        校验状态 = "",
                        是否正在烧录 = "",
                    };
                    m_dicDogList.Add(m_dicDogList.Count.ToString(), dogitem);
                }
            }
        }

        public async Task<string> get_enable_dogList()
        {
            string jsStr = JsonConvert.SerializeObject(new { err = "DMS连接错误" });
            try
            {
                using (var httpclient = new HttpClient())//不需要设置header可以使用GetAsync调用
                {
                    string uriTask = "http://api.lanrenshi.com/get_doglist";
                    var uri = new UriBuilder(uriTask)
                    {
                        Port = -1,//表示不使用任何端口号。这通常用于将 URI 的端口重置为默认端口，即使用协议默认的端口，例如 80（HTTP）或 443（HTTPS）
                    }.Uri;

                    var response = await httpclient.GetAsync(uri);
                    if (response.IsSuccessStatusCode)
                    {
                        var content = await response.Content.ReadAsStringAsync();
                        JObject obj = JObject.Parse(content);
                        JArray 加密狗列表 = (JArray)obj["加密狗列表"];
                        foreach (JObject item in 加密狗列表)
                        {
                            var 物料编码 = item.GetValue("物料编码").ToString();
                            var 物料名称 = item.GetValue("物料名称").ToString();
                            var 规格型号 = item.GetValue("物料规格").ToString();
                            if (!m_dicDogList_new.TryGetValue(物料编码, out var val))
                            {
                                CsDogitem dogitem = new CsDogitem()
                                {
                                    物料编码 = 物料编码,
                                    物料名称 = 物料名称,
                                    规格型号 = 规格型号,
                                };
                                m_dicDogList_new.Add(物料编码, dogitem);
                            }
                        }
                    }
                    else
                    {
                        return jsStr;
                    }
                    return jsStr = JsonConvert.SerializeObject(new { msg = "获取加密狗列表信息成功" });
                }
            }
            catch (Exception ex)
            {
                return jsStr;
            }
        }

        public async Task<string> register_dog(string dogInfo)
        {
            string jsStr = JsonConvert.SerializeObject(new { err = "DMS连接错误" });
            try
            {
                using (var httpclient = new HttpClient())//不需要设置header可以使用GetAsync调用
                {
                    string uriTask = "http://api.lanrenshi.com/register_dog?";
                    var uri = new UriBuilder(uriTask)
                    {
                        Port = -1,//表示不使用任何端口号。这通常用于将 URI 的端口重置为默认端口，即使用协议默认的端口，例如 80（HTTP）或 443（HTTPS）
                        Query = $"&token=laser&dogInfo={dogInfo}"
                    }.Uri;

                    var response = await httpclient.GetAsync(uri);
                    if (response.IsSuccessStatusCode)
                    {
                        //var content = await response.Content.ReadAsStringAsync();
                        jsStr = await response.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        return jsStr;
                    }
                    return jsStr = JsonConvert.SerializeObject(new { msg = "烧录信息注册成功" });
                }
            }
            catch (Exception ex)
            {
                return jsStr;
            }
        }

        public async Task<string> check_dog(string dogInfo)
        {
            string jsStr = JsonConvert.SerializeObject(new { err = "DMS连接错误" });
            try
            {
                using (var httpclient = new HttpClient())//不需要设置header可以使用GetAsync调用
                {
                    string uriTask = "http://api.lanrenshi.com/check_dog?";
                    var uri = new UriBuilder(uriTask)
                    {
                        Port = -1,//表示不使用任何端口号。这通常用于将 URI 的端口重置为默认端口，即使用协议默认的端口，例如 80（HTTP）或 443（HTTPS）
                        Query = $"&token=laser&dogInfo={dogInfo}"
                    }.Uri;

                    var response = await httpclient.GetAsync(uri);
                    if (response.IsSuccessStatusCode)
                    {
                        //var content = await response.Content.ReadAsStringAsync();
                        return jsStr = await response.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        return jsStr;
                    }
                }
            }
            catch (Exception ex)
            {
                return jsStr;
            }
        }

        public void RefreshDogList()
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                m_DogList.Clear();
                foreach (var item in m_dicDogList)
                    m_DogList.Add(item.Value);
            });
        }

        #region UI数据显示

        private string _任务序号 = "";
        public string 任务序号
        {
            get { return _任务序号; }
            set { if (_任务序号 != value) { _任务序号 = value; RaisePropertyChanged(""); } }
        }

        private string _任务状态 = "未开始";
        public string 任务状态
        {
            get { return _任务状态; }
            set { if (_任务状态 != value) { _任务状态 = value; RaisePropertyChanged(""); } }
        }

        private string _母狗状态 = "未存在";
        public string 母狗状态
        {
            get { return _母狗状态; }
            set { if (_母狗状态 != value) { _母狗状态 = value; RaisePropertyChanged(""); } }
        }

        private bool 是否可烧录 = false;
        private string _子狗状态 = "未存在";
        public string 子狗状态
        {
            get { return _子狗状态; }
            set
            {
                if (_子狗状态 != value)
                {
                    _子狗状态 = value; RaisePropertyChanged("");
                    if (_子狗状态.Equals("存在"))
                        是否可烧录 = true;
                    else
                        是否可烧录 = false;
                }
            }
        }

        private string _线程状态 = "闲置中";
        public string 线程状态
        {
            get { return _线程状态; }
            set { if (_线程状态 != value) { _线程状态 = value; RaisePropertyChanged(""); } }
        }

        //仅做绑定显示
        private ObservableCollection<CsDogitem> _m_DogList = new ObservableCollection<CsDogitem>();
        public ObservableCollection<CsDogitem> m_DogList
        {
            get { return _m_DogList; }
            set { if (_m_DogList != value) { _m_DogList = value; RaisePropertyChanged(""); } }
        }

        public class CsDogitem
        {
            public bool 选择 { get; set; }
            public string 序号 { get; set; }
            public string 物料编码 { get; set; }
            public string 物料名称 { get; set; }
            public string 规格型号 { get; set; }
            public string 激活码 { get; set; }
            public string 加密狗ID { get; set; }
            public string 创建时间 { get; set; }
            public string 任务单ID { get; set; }
            public string 烧录状态 { get; set; }
            public string 校验状态 { get; set; }
            public string 是否正在烧录 { get; set; }
        }
        #endregion

    }

}
